#include "record_manager.h"
#include "hilog.h"
#include "hifunction.h"
#include "json.h"

#define RES_CODE_SUCCES 200 //成功
#define RES_CODE_FAILED 400 //失败

#define DEV_STATE_FREE 1 //空闲
#define DEV_STATE_RECORDING 2 //正在录制
#define DEV_STATE_OFFLINE 3 //离线

 RecordManager::RecordManager()
 {
     map_record_uitl_.clear();
 }

RecordManager::~RecordManager()
{

}

string RecordManager::start_record(vector<string> params)
{
    hi_trace("******");
    int ret = RES_CODE_SUCCES;    
    int dev_state = DEV_STATE_OFFLINE;
    string msg = "";

    int uniqueCode = atoi(params[1].c_str());
    string user = params[2].c_str();
    string flowUrl = params[3].c_str();
    string path = params[4].c_str();
    string callbackurl = params[5].c_str();
    string otherParam = params[6].c_str();
    
    lock_map_record_util_.lock();
    map<int, RecordUtil*>::iterator itr;    
    itr = map_record_uitl_.find(uniqueCode);             
    if(itr == map_record_uitl_.end()) {        
        RecordUtil* ptr_record_util = new RecordUtil;  
        ptr_record_util->start_record(uniqueCode,user,flowUrl,path,callbackurl,otherParam);        
        map_record_uitl_.insert(map<int, RecordUtil*>::value_type(uniqueCode, ptr_record_util));
        dev_state = DEV_STATE_RECORDING;  
    } 
    else {
        hi_error("record obj have exited!");
        ret = RES_CODE_FAILED;
    }   
    lock_map_record_util_.unlock();

    Json resJson = Json::object({
        {"code", ret},
        {"isOnLine", dev_state},
        {"msg", msg.c_str()}
    });

    return resJson.toJson(Doc::Indent);
}

string RecordManager::stop_record(vector<string>& params)
{    
    int ret = RES_CODE_SUCCES;    
    int dev_state = DEV_STATE_OFFLINE;
    string msg = "";

    int uniqueCode = atoi(params[1].c_str());
    
    lock_map_record_util_.lock();    
    map<int, RecordUtil*>::iterator itr;
    itr = map_record_uitl_.find(uniqueCode);            
    if(itr != map_record_uitl_.end()) {
        RecordUtil* ptr = (RecordUtil*)itr->second;
        ptr->stop_record();
        map_record_uitl_.erase(itr);
    }
    else {
        hi_warn("no find record obj unicode: %d", uniqueCode);                   
    }    
    lock_map_record_util_.unlock();    

    Json resJson = Json::object({
        {"code", ret},
        {"isOnLine", dev_state},
        {"msg", msg.c_str()}
    });

    return resJson.toJson(Doc::Indent);
}

string RecordManager::get_record_state(vector<string> params)
{
    int ret = RES_CODE_SUCCES;    
    int dev_state = DEV_STATE_OFFLINE;
    string msg = "";
    bool bfind = false; 

    int uniqueCode = atoi(params[1].c_str());
    string flowUrl = params[2].c_str();

    lock_map_record_util_.lock();    
    map<int, RecordUtil*>::iterator itr;
    itr = map_record_uitl_.find(uniqueCode);            
    if(itr != map_record_uitl_.end()) {
        //返回设备状态
        bfind = true;
        RecordUtil* ptr = (RecordUtil*)itr->second;
        //判断流是否正常
        if(check_stream(flowUrl)) {
            dev_state = DEV_STATE_RECORDING;
            msg = ptr->get_user();
        }
        else {
            //掉线了
            hi_error("record url: %s exception stop.", flowUrl.c_str());
            map_record_uitl_.erase(itr);                
        }           
    }
    lock_map_record_util_.unlock(); 

    if(!bfind) {
        //查看流地址是否有
        hi_warn("no find record obj unicode: %d", uniqueCode);         
        stringstream ss;
        ss<<get_app_path()<<"ffmpeg -rw_timeout 8000000 -i "<<flowUrl<<" -vcodec copy -acodec copy -y -to 00:00:01 check.mp4";
        //hi_trace("%s",ss.str().c_str());
        char result[1024] = {0};
        int rescmd = proc_shell_cmd((char*)ss.str().c_str(), result); 
        if(rescmd < 0) {
            ret = RES_CODE_FAILED;                
        }
        else {
            string str(result);        
            if(str.find("exit_program 0") == string::npos) {
                hi_error("offline url: %s", flowUrl.c_str());
                dev_state = DEV_STATE_OFFLINE;
            }
            else {
                dev_state = DEV_STATE_FREE;
            }
        }                    
    }    
 
     Json resJson = Json::object({
        {"code", ret},
        {"isOnLine", dev_state},
        {"msg", msg.c_str()}
    });

    return resJson.toJson(Doc::Indent);
}

bool RecordManager::check_stream(const string& url)
{
    stringstream ss;
    ss<<get_app_path()<<"ffmpeg -rw_timeout 8000000 -i "<<url<<" -vcodec copy -acodec copy -y -to 00:00:01 check.mp4";
    //hi_trace("%s",ss.str().c_str());
    char result[1024] = {0};
    int rescmd = proc_shell_cmd((char*)ss.str().c_str(), result); 
    if(rescmd < 0) {        
        return false;          
    }
    else {
        string str(result);        
        if(str.find("exit_program 0") == string::npos) {
            hi_error("offline url: %s", url.c_str());
            return false;
        }
        else {
            return true;
        }
    }

    return true;
}